#include "stdafx.h"
#include "snetwork/Session.h"
#include "snetwork/Cookie.h"
#include "standard/md5.h"
#include "standard/nstring.h"
#include "Theadlib/create.h"
#include "Theadlib/thread.h"

namespace Sock
{
    Session *Session::m_instance = NULL;
    
    Session *Session::instance()
    {
        if (m_instance==NULL) {
            m_instance = new Session();
        }
        return m_instance;
    }
        
    Session::Session()
    {
        m_sid.clear();
    }    
        
    std::string Session::session_id()
    {
        return m_sid;
    } 
    
    void Session::session_id(std::string s_id)
    {
        m_sid = s_id;
    } 
        
    bool Session::session_start()
    {
        struct timeval tv;

		tv.tv_sec = 1;
		tv.tv_usec = 0;
        //time_t now;
        char buf[100];
        long int rdnum = 0;                
        
        if (n_CookieRecv["HTTPDSID"].empty()) {        
            memset(buf, 0, sizeof(buf)); 
            
            if (m_sid.empty()) {                      
                const char *remote_addr = n_clientip.c_str();        
                srand( (unsigned int)time( NULL ) );
                rdnum = rand()%(99999999);
                
                sprintf(buf, "%.15s%ld%ld%08ld", 
                    remote_addr ? remote_addr : "", 
                    tv.tv_sec, (long int)tv.tv_usec, rdnum);
                
                m_sid.append(buf, strlen(buf));
            }
            
            Cookie cook;        
            char md5str[33];
            
            md5(md5str, buf);
            std::string scok(md5str);
            
            n_Cookie["HTTPDSID"] = scok;            
            scok += "|/"; 
            cook.SetCookie("HTTPDSID|path", scok);
        }
        
        return true;
    }    
    
    bool Session::SetSession(std::string name, std::string value)
    {
        n_Session[name] = value;                        
        return true;
    }
        
    /**
     * execute
     */
    std::string Session::execute()
    {
        mapStrStr::iterator sess;
        std::string sess_str;
        
        sess_str.clear();
        if (!n_Session.empty()) {
            for ( sess = n_Session.begin(); sess != n_Session.end(); sess++ ) {
                std::string val_len = itos((sess->second).length());
                sess_str += sess->first + "|s:" + val_len + ":" + sess->second + ";";
            }
        }
        return sess_str;
    }
    
    std::string Session::GetSession(std::string name)
    {      
        std::string ret;
        
        ret.clear();
        if ( !n_Session[name].empty() ) {
            ret = n_Session[name];
        }
                
        return ret;
    }
}
